package gggameserver.testbed;

import java.io.File;
import java.io.IOException;

import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.connection.ConnectionException;
import net.schmizz.sshj.connection.channel.direct.Session;
import net.schmizz.sshj.connection.channel.direct.Session.Command;
import net.schmizz.sshj.transport.TransportException;
import gggameserver.util.GGConfiguration;

public class GGMirror {

	String mirrorName;
	String host_fp;
	String host;
	String user;
	String password;
	String testbed;
	
	SSHClient ssh;
	
	private GGMirror() {}
	
	public GGMirror(String mirrorName) {
		this.mirrorName = mirrorName;
		this.host_fp = GGConfiguration.getProperty("m-testbed." + mirrorName + ".host_fingerprint");
		this.host = GGConfiguration.getProperty("m-testbed." + mirrorName + ".host");
		this.user = GGConfiguration.getProperty("m-testbed." + mirrorName + ".user");
		this.password = GGConfiguration.getProperty("m-testbed." + mirrorName + ".password");
		this.testbed = GGConfiguration.getProperty("m-testbed." + mirrorName + ".testbed");
	}
	
	public GGCommandResult execRes(String cmdline) {
		Command cmd = null;
		try {
			String command = "bash -c \"" + cmdline + "\"";
			cmd = ssh.startSession().exec(command);
			System.out.print("** > " + command);
			return new GGCommandResult(cmd);
		} catch (ConnectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransportException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}
	
	public Command exec(String cmdline) {
		Command cmd = null;
		try {
			String command = "bash -c \"" + cmdline + "\"";
			cmd = ssh.startSession().exec(command);
			System.out.print("** > " + command);
			return cmd;
		} catch (ConnectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransportException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}
	
	public boolean execute(String cmdline) {
		Command cmd;
		try {
			String command = "bash -c \"" + cmdline + "\"";
			cmd = ssh.startSession().exec(command);
			System.out.print("** > " + command);
	        GGCommandResult res = new GGCommandResult(cmd);
	        System.out.print(res.getLog());
	        System.out.println("\n** exit status: " + res.getExitCode());
			return true;
		} catch (ConnectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransportException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return false;
	}
	
	public boolean copyToMirrorAbsolute(File file, String to, String filename) {
        try {
            final String src = file.getCanonicalPath();
            final String target = to + "/" + filename; // TODO 
System.out.println("mirror=" + this.mirrorName + " " + this.user + "@" + this.host +  " copyToMirrorAbsolute '" + src + "' -> '" + target + "'");
            ssh.newSCPFileTransfer().upload(src, target);
            
            return true;
        } catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
        }
	
        return false;
	}
	
	public boolean copyToMirror(File file, String to) {
        try {
            final String src = file.getCanonicalPath();
            final String target = this.testbed + "/" + to + "/" + file.getName(); // TODO 
System.out.println("mirror=" + this.mirrorName + " " + this.user + "@" + this.host +  " copyToMirror '" + src + "' -> '" + target + "'");
            ssh.newSCPFileTransfer().upload(src, target);
            
            return true;
        } catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
        }
	
        return false;
	}
	
	public boolean copyFromMirror(String filename, File file) {
        try {
            final String localPath = new File(file, filename).getCanonicalPath();
            final String source = this.testbed + "/" + filename; // TODO 
System.out.println("copyFromMirror '" + source + "' -> '" + localPath + "'");
            ssh.newSCPFileTransfer().download(source, localPath);
            
            return true;
        } catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
        }
	
        return false;
	}
	
	public boolean connect() {
		if (null != ssh) return true;

        this.ssh = new SSHClient();
        ssh.addHostKeyVerifier(this.host_fp);

        try {
System.out.println("Connecting to '" + this.user + "@" + this.host + "'");
            ssh.connect(this.host);
        	ssh.authPassword(this.user, this.password);
            return true;
        } catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
        }
        
        return false;
	}

	public void disconnect() {
		if (null == ssh) return;
		
        try {
			ssh.disconnect();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			ssh = null;
		}
	}

	public String getTestBedPath() {
		return this.testbed;
	}
	
	public GGMirror getCopy() {
		GGMirror m = new GGMirror();
		m.mirrorName = this.mirrorName;
		m.host_fp = this.host_fp;
		m.host = this.host;
		m.user = this.user;
		m.password = this.password;
		m.testbed = this.testbed;
		return m;
	}

}
